package mails;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.FetchProfile;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.FolderClosedException;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.event.MessageCountAdapter;
import javax.mail.event.MessageCountEvent;
import javax.mail.internet.InternetAddress;

import services.Services;

import com.sun.mail.imap.IMAPFolder;

import data.Complaint;
import data.Staff;

public class MailUser {

	Services services;
	String protocol = "imap";
	String incomingServer = "imap.gmail.com";
	int incomingPort = 993;
	int frequently = 18000;
	String outgoingServer = "smtp.gmail.com";
	int outgoingPort = 587;
	String mbox = "Inbox";
	String userName = "tam.dinhvantam@gmail.com";
	String password = "!@#456&*(!";

	/**
	 * Instantiates a new mail user.
	 * 
	 * @param services
	 *            the services
	 */
	public MailUser(Services services) {
		this.services = services;
	}

	/**
	 * Instantiates a new mail user.
	 */
	private MailUser() {
	}

	/**
	 * Load setting.
	 */
	private void loadSetting() {
		Properties settings = new Properties();
		settings.put("mail.protocol", protocol);
		settings.put("mail.incomingServer", incomingServer);
		settings.put("mail.incomingPort", String.valueOf(incomingPort));
		settings.put("mail.outcomingServer", outgoingServer);
		settings.put("mail.outcomingPort", String.valueOf(outgoingPort));
		settings.put("mail.folder", mbox);
		settings.put("mail.username", userName);
		settings.put("mail.password", password);

		try {
			// Check File exist
			File file = new File("mail_config.properties");
			if (file.exists()) {
				// Load Setting File
				FileInputStream in = new FileInputStream(file);
				settings.load(in);

				// Change Default Setting
				protocol = settings.getProperty("mail.protocol");
				incomingServer = settings.getProperty("mail.incomingServer");
				incomingPort = Integer.parseInt(settings
						.getProperty("mail.incomingPort"));
				outgoingServer = settings.getProperty("mail.outcomingServer");
				outgoingPort = Integer.parseInt(settings
						.getProperty("mail.outcomingPort"));
				mbox = settings.getProperty("mail.folder");
				userName = settings.getProperty("mail.username");
				password = settings.getProperty("mail.password");
			} else {
				file.createNewFile();
				FileOutputStream out = new FileOutputStream(file);
				settings.store(out, "JavaMail Configuration File");
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void login() {
		try {
			// Load Setting
			loadSetting();
			// Get properties system
			Properties props = System.getProperties();
			props.setProperty("mail.imap.socketFactory.class",
					"javax.net.ssl.SSLSocketFactory");
			props.setProperty("mail.imap.socketFactory.fallback", "false");

			// Get a Session object
			Session session = Session.getInstance(props, null);
			// session.setDebug(true);

			// Get a Store object
			Store store = session.getStore(protocol);

			// Connect
			store.connect(incomingServer, incomingPort, userName, password);

			// Open a Folder
			Folder folder = store.getFolder(mbox);
			if (folder == null || !folder.exists()) {
				System.out.println("Invalid folder");
				System.exit(1);
			}

			folder.open(Folder.READ_WRITE);

			// Add messageCountListener to listen for new messages
			folder.addMessageCountListener(new MessageCountAdapter() {
				public void messagesAdded(MessageCountEvent ev) {
					Message[] msgs = ev.getMessages();

					// Just dump out the new messages
					for (int i = 0; i < msgs.length; i++) {
						try {
							String title = msgs[i].getSubject();
							String description = msgs[i].getContent()
									.toString();
							Complaint complaint = new Complaint();
							complaint.setComplaintTitle(title);
							complaint.setComplaintDescription(description);
							String sender = msgs[i].getFrom()[0].toString();
							int staffId = services.getStaffIDByEmail(sender);
							complaint.setStaff(new Staff(staffId));
							services.createComplaint(complaint);
						} catch (IOException ioex) {
							ioex.printStackTrace();
						} catch (MessagingException mex) {
							mex.printStackTrace();
						}
					}
				}
			});

			// Check mail once in "freq" MILLIseconds
			boolean supportsIdle = false;
			try {
				if (folder instanceof IMAPFolder) {
					IMAPFolder f = (IMAPFolder) folder;

					f.idle();
					supportsIdle = true;
				}
			} catch (FolderClosedException fex) {
				throw fex;
			} catch (MessagingException mex) {
				supportsIdle = false;
			}
			for (;;) {
				if (supportsIdle && folder instanceof IMAPFolder) {
					IMAPFolder f = (IMAPFolder) folder;
					f.idle();
				} else {
					Thread.sleep(frequently); // sleep for freq milliseconds

					// This is to force the IMAP server to send us
					// EXISTS notifications.
					folder.getMessageCount();
				}
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

//	public void login() {
//		try {
//			// Load Setting
//			loadSetting();
//			// Get properties system
//			Properties props = System.getProperties();
//			props.setProperty("mail.imap.socketFactory.class",
//					"javax.net.ssl.SSLSocketFactory");
//			props.setProperty("mail.imap.socketFactory.fallback", "false");
//
//			// Get a Session object
//			Session session = Session.getInstance(props, null);
//			Store store = session.getStore(protocol);
//			store.connect(incomingServer, incomingPort, userName, password);
//			Folder folder = store.getDefaultFolder();
//			folder = folder.getFolder(mbox);
//			folder.open(Folder.READ_WRITE);
//			// Attributes & Flags for all messages ..
//			Message[] msgs = folder.getMessages();
//
//			// Use a suitable FetchProfile
//			FetchProfile fp = new FetchProfile();
//			fp.add(FetchProfile.Item.ENVELOPE);
//			fp.add(FetchProfile.Item.FLAGS);
//			fp.add("X-Mailer");
//			folder.fetch(msgs, fp);
//
//			for (int i = 0; i < msgs.length; i++) {
//				System.out.println("--------------------------");
//				System.out.println("MESSAGE #" + (i + 1) + ":");
//				dumpEnvelope(msgs[i]);
//				// dumpPart(msgs[i]);
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//			// TODO: handle exception
//		}
//	}
//
//	public static void dumpEnvelope(Message m) throws Exception {
//		System.out.println("This is the message envelope");
//		System.out.println("---------------------------");
//		Address[] a;
//		// FROM
//		if ((a = m.getFrom()) != null) {
//			for (int j = 0; j < a.length; j++)
//				System.out.println("FROM: " + a[j].toString());
//		}
//
//		// REPLY TO
//		if ((a = m.getReplyTo()) != null) {
//			for (int j = 0; j < a.length; j++)
//				System.out.println("REPLY TO: " + a[j].toString());
//		}
//
//		// TO
//		if ((a = m.getRecipients(Message.RecipientType.TO)) != null) {
//			for (int j = 0; j < a.length; j++) {
//				System.out.println("TO: " + a[j].toString());
//				InternetAddress ia = (InternetAddress) a[j];
//				if (ia.isGroup()) {
//					InternetAddress[] aa = ia.getGroup(false);
//					for (int k = 0; k < aa.length; k++)
//						System.out.println("  GROUP: " + aa[k].toString());
//				}
//			}
//		}
//
//		// SUBJECT
//		System.out.println("SUBJECT: " + m.getSubject());
//
//		// DATE
//		Date d = m.getSentDate();
//		System.out.println("SendDate: "
//				+ (d != null ? d.toString() : "UNKNOWN"));
//
//		// FLAGS
//		Flags flags = m.getFlags();
//		StringBuffer sb = new StringBuffer();
//		Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags
//
//		boolean first = true;
//		for (int i = 0; i < sf.length; i++) {
//			String s;
//			Flags.Flag f = sf[i];
//			if (f == Flags.Flag.ANSWERED)
//				s = "\\Answered";
//			else if (f == Flags.Flag.DELETED)
//				s = "\\Deleted";
//			else if (f == Flags.Flag.DRAFT)
//				s = "\\Draft";
//			else if (f == Flags.Flag.FLAGGED)
//				s = "\\Flagged";
//			else if (f == Flags.Flag.RECENT)
//				s = "\\Recent";
//			else if (f == Flags.Flag.SEEN)
//				s = "\\Seen";
//			else
//				continue; // skip it
//			if (first)
//				first = false;
//			else
//				sb.append(' ');
//			sb.append(s);
//		}
//
//		String[] uf = flags.getUserFlags(); // get the user flag strings
//		for (int i = 0; i < uf.length; i++) {
//			if (first)
//				first = false;
//			else
//				sb.append(' ');
//			sb.append(uf[i]);
//		}
//		System.out.println("FLAGS: " + sb.toString());
//
//		// X-MAILER
//		String[] hdrs = m.getHeader("X-Mailer");
//		if (hdrs != null)
//			System.out.println("X-Mailer: " + hdrs[0]);
//		else
//			System.out.println("X-Mailer NOT available");
//		System.out.println(m.getContent());
//	}
//
//	public static void main(String[] args) {
//		MailUser mail = new MailUser();
//		mail.login();
//	}

}
